package com.gzx.plugin.data.wxjk.service.impl;

import com.alibaba.fastjson2.JSON;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.gzx.plugin.data.core.consts.CompanyConstants;
import com.gzx.plugin.data.core.utils.BirthToolUtil;
import com.gzx.plugin.data.wxjk.entity.DataWxjkSssj;
import com.gzx.plugin.data.wxjk.service.ITjzyWxjkService;
import com.gzx.tjzy.feign.GzxCaseFeign;
import com.gzx.tjzy.feign.GzxDebtorInfoFeign;
import com.gzx.tjzy.feign.GzxDebtorLiaisonFeign;
import com.gzx.tjzy.feign.req.debtor.GzxDebtorInfoReqDto;
import com.gzx.tjzy.feign.req.gzxcase.GzxCaseDetailReqDto;
import com.gzx.tjzy.feign.req.gzxcase.GzxCaseReqDto;
import com.gzx.tjzy.feign.req.liaison.GzxDebtorLiaisonReqDto;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import vip.xiaonuo.common.util.CommonCryptogramUtil;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;

@Slf4j
@Service
@DS("data")
@RequiredArgsConstructor
public class TjzyWxjkServiceImpl implements ITjzyWxjkService {

    private final DataWxjkContactInfoServiceImpl dataWxjkContactInfoService;

    private final GzxCaseFeign gzxCaseFeign;
    private final GzxDebtorInfoFeign gzxDebtorInfoFeign;
    private final GzxDebtorLiaisonFeign gzxDebtorLiaisonFeign;

    @Override
    public void batchCase(List<DataWxjkSssj> dataList, String batchNumber) {
        log.info("本次接收维信金科数据:{}", dataList.size());
        Map<String, GzxCaseReqDto> memCache = new HashMap<>();
        for (DataWxjkSssj data : dataList) {
            String uniKey = CompanyConstants.WXJK_PROJECT_CODE + batchNumber + data.getIdNo();
            GzxCaseReqDto gzxCase = memCache.get(uniKey);
            if (gzxCase == null) {
                gzxCase = new GzxCaseReqDto();
                //同步字段信息
                gzxCase.setCompanyCode(CompanyConstants.WXJK_COMPANY_CODE);
                gzxCase.setProductCode(CompanyConstants.WXJK_PRODUCT_CODE);
                gzxCase.setProjectCode(CompanyConstants.WXJK_PROJECT_CODE);
                gzxCase.setBatchNumber(batchNumber);
                gzxCase.setDebtorName(data.getCustName());
                gzxCase.setDebtorCardId(CommonCryptogramUtil.doSm1AesEncrypt(data.getIdNo()));
                gzxCase.setDebtorPhone(CommonCryptogramUtil.doSm1AesEncrypt(data.getPhone()));
                gzxCase.setLoanAmount(data.getLoanAmount());
                gzxCase.setOverdueAmount(data.getOverdueTotalAmount());
                gzxCase.setCleanLoanAmount(data.getCleanLoanTotalAmount());//应催金额汇总
                gzxCase.setCaseStatus(1);//初始值设置未归户
                gzxCase.setOverdueStatus(1);
                gzxCase.setPartnerBusinessId(String.valueOf(data.getBusinessId()));//关联甲方系统的唯一id，方便后续系统查询

                //判断性别1男2女
                if ("男".equals(data.getSex())) {
                    gzxCase.setDebtorSex(1);
                } else {
                    gzxCase.setDebtorSex(2);
                }
            } else {
                // 计算贷款总金额 ，检查oldAmount是否为空，如果为空则设置为零
                BigDecimal safeOldAmount = (gzxCase.getLoanAmount() == null) ? BigDecimal.ZERO : gzxCase.getLoanAmount();
                // 检查newAmount是否为空，如果为空则设置为零
                BigDecimal safeNewAmount = (data.getLoanAmount() == null) ? BigDecimal.ZERO : data.getLoanAmount();
                BigDecimal totalAmount = safeOldAmount.add(safeNewAmount);
                gzxCase.setLoanAmount(totalAmount);

                // 计算逾期总金额，检查oldAmount是否为空，如果为空则设置为零
                BigDecimal safeOldOverdueAmount = (gzxCase.getOverdueAmount() == null) ? BigDecimal.ZERO : gzxCase.getOverdueAmount();
                // 检查newAmount是否为空，如果为空则设置为零
                BigDecimal safeNewOverdueAmount = (data.getOverdueTotalAmount() == null) ? BigDecimal.ZERO : data.getOverdueTotalAmount();
                BigDecimal overdueAmount = safeOldOverdueAmount.add(safeNewOverdueAmount);
                gzxCase.setOverdueAmount(overdueAmount);

                // 计算应催总金额，汇总，检查oldAmount是否为空，如果为空则设置为零
                BigDecimal safeOldCleanLoanTotalAmount = (gzxCase.getCleanLoanAmount() == null) ? BigDecimal.ZERO : gzxCase.getCleanLoanAmount();
                // 检查newAmount是否为空，如果为空则设置为零
                BigDecimal safeNewCleanLoanTotalAmount = (data.getCleanLoanTotalAmount() == null) ? BigDecimal.ZERO : data.getCleanLoanTotalAmount();
                BigDecimal cleanLoanTotalAmount = safeOldCleanLoanTotalAmount.add(safeNewCleanLoanTotalAmount);
                gzxCase.setCleanLoanAmount(cleanLoanTotalAmount);
            }
            memCache.put(uniKey, gzxCase);
        }

        //每2000个调用一次tjzy的feign接口
        int batchSize = 2000;
        List<GzxCaseReqDto> gzxCaseList = new ArrayList<>();
        gzxCaseList.addAll(memCache.values());
        for (int i = 0; i < gzxCaseList.size(); i += batchSize) {
            int endIndex = Math.min(i + batchSize, gzxCaseList.size());
            List<GzxCaseReqDto> subList = gzxCaseList.subList(i, endIndex);

            gzxCaseFeign.caseSync(subList);

            try {
                Thread.sleep(200L);
            } catch (InterruptedException e) {
                log.info("中断线程异常，不影响，继续执行。。。。");
            }
        }
        log.info("本次接收维信金科明细数据:{}条,用户维度数据:{}条", dataList.size(), gzxCaseList.size());
    }

    @Override
    public void batchCaseDetail(List<DataWxjkSssj> dataList, String batchNumber) {
        List<GzxCaseDetailReqDto> resultList = new ArrayList<>();
        try {
            for (DataWxjkSssj sssjInfo : dataList) {
                GzxCaseDetailReqDto gzxCaseDetail = new GzxCaseDetailReqDto();
                gzxCaseDetail.setContractNo(sssjInfo.getContractNo() == null ? "" : sssjInfo.getContractNo());//借款合同编号
                gzxCaseDetail.setDebtorCardId(CommonCryptogramUtil.doSm1AesEncrypt(sssjInfo.getIdNo()));//身份证号
                gzxCaseDetail.setLoanAmount(sssjInfo.getLoanAmount() == null ? new BigDecimal(0) : sssjInfo.getLoanAmount());//放贷金额	单位：元
                gzxCaseDetail.setContractRate(sssjInfo.getContractPenalty() == null ? new BigDecimal(0) : sssjInfo.getContractPenalty());//合同年利率
                gzxCaseDetail.setLoanDate(String.valueOf(sssjInfo.getDeliveryDate()));//放贷日期	格式:yyyy-mm-dd hh24:mi:ss
                gzxCaseDetail.setBankAccount(CommonCryptogramUtil.doSm1AesEncrypt(sssjInfo.getBankCardNo()));//借款人收款账户卡号
                gzxCaseDetail.setBankName(sssjInfo.getBankName() == null ? "" : sssjInfo.getBankName());//借款人收款账户所属银行
                gzxCaseDetail.setFunder(sssjInfo.getLendingSide() + '-' + sssjInfo.getProductName());//放款方+产品名称, 因为维信是助贷模式，拼接一个产品方便坐席识别
                gzxCaseDetail.setTotalPeriod(sssjInfo.getLoanPeriod());//贷款期数
                gzxCaseDetail.setOverdueAmount(sssjInfo.getOverdueTotalAmount() == null ? new BigDecimal(0) : sssjInfo.getOverdueTotalAmount());
                gzxCaseDetail.setOverdueDate(String.valueOf(sssjInfo.getOverdueDate()));
                gzxCaseDetail.setBatchNumber(batchNumber);//设置批次号，自动生成
                gzxCaseDetail.setPartnerBusinessId(String.valueOf(sssjInfo.getBusinessId()));//甲方系统的唯一id

                //保存json串的时候要讲敏感字段加密后再保存
                DataWxjkSssj encryptSssjINfo = new DataWxjkSssj();
                BeanUtils.copyProperties(sssjInfo, encryptSssjINfo);
                encryptSssjINfo.setIdNo(CommonCryptogramUtil.doSm1AesEncrypt(sssjInfo.getIdNo()));
                encryptSssjINfo.setBankCardNo(CommonCryptogramUtil.doSm1AesEncrypt(sssjInfo.getBankCardNo()));
                encryptSssjINfo.setResAddress(CommonCryptogramUtil.doSm1AesEncrypt(sssjInfo.getResAddress()));
                encryptSssjINfo.setResidAddress(CommonCryptogramUtil.doSm1AesEncrypt(sssjInfo.getResidAddress()));
                encryptSssjINfo.setPhone(CommonCryptogramUtil.doSm1AesEncrypt(sssjInfo.getPhone()));
                gzxCaseDetail.setAllDetail(JSON.toJSONString(encryptSssjINfo));//全部字段都存起来，避免页面展示信息不全
                resultList.add(gzxCaseDetail);
            }

            int batchSize = 2000;
            for (int i = 0; i < resultList.size(); i += batchSize) {
                int endIndex = Math.min(i + batchSize, resultList.size());
                List<GzxCaseDetailReqDto> subList = resultList.subList(i, endIndex);

                gzxCaseFeign.caseDetailSync(subList);

                try {
                    Thread.sleep(200L);
                } catch (InterruptedException e) {
                    log.info("中断线程异常，不影响，继续执行。。。。");
                }
            }
        } catch (Exception e) {
            log.error("批量保存detail异常", e);
        }
    }

    @Override
    public void batchDebtorInfo(List<DataWxjkSssj> dataList) {
        List<GzxDebtorInfoReqDto> resultList = new ArrayList<>();
        for (DataWxjkSssj data : dataList) {
            GzxDebtorInfoReqDto gzxDebtorInfo = new GzxDebtorInfoReqDto();
            gzxDebtorInfo.setDebtorName(data.getCustName());
            gzxDebtorInfo.setDebtorBirth(BirthToolUtil.getBirth(data.getIdNo()));
            gzxDebtorInfo.setProjectCode(CompanyConstants.WXJK_PROJECT_CODE);
            //获取年龄
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
            LocalDate date = LocalDate.parse(BirthToolUtil.getBirth(data.getIdNo()), formatter);
            //获取当前年份
            Calendar calendar = Calendar.getInstance();
            int year = calendar.get(Calendar.YEAR);

            gzxDebtorInfo.setDebtorAge(year - date.getYear());
            gzxDebtorInfo.setDebtorProvince(data.getIdNo().substring(0, 3));
            gzxDebtorInfo.setDebtorCity(data.getIdNo().substring(3, 6));
            gzxDebtorInfo.setDebtorAddress(CommonCryptogramUtil.doSm1AesEncrypt(data.getResidAddress()));//户籍地
            gzxDebtorInfo.setDebtorNowAddress(CommonCryptogramUtil.doSm1AesEncrypt(data.getResAddress()));//联系地址
            gzxDebtorInfo.setDebtorCardId(CommonCryptogramUtil.doSm1AesEncrypt(data.getIdNo()));//身份证
            gzxDebtorInfo.setDebtorPhone(CommonCryptogramUtil.doSm1AesEncrypt(data.getPhone()));//手机号

            //判断性别1男2女
            if ("男".equals(data.getSex())) {
                gzxDebtorInfo.setDebtorSex(1);
            } else {
                gzxDebtorInfo.setDebtorSex(2);
            }
            resultList.add(gzxDebtorInfo);
        }

        int batchSize = 2000;
        for (int i = 0; i < resultList.size(); i += batchSize) {
            int endIndex = Math.min(i + batchSize, resultList.size());
            List<GzxDebtorInfoReqDto> subList = resultList.subList(i, endIndex);

            gzxDebtorInfoFeign.sync(subList);

            try {
                Thread.sleep(200L);
            } catch (InterruptedException e) {
                log.info("中断线程异常，不影响，继续执行。。。。");
            }
        }
    }

    @Override
    public void batchDebtorRelationPhone(List<DataWxjkSssj> dataList) {
        Map<Long, String> map = new HashMap<>();
        Map<Long, String> tempMap = new HashMap<>();
        for (DataWxjkSssj wxjkSssjInfo : dataList) {
            map.put(wxjkSssjInfo.getBusinessId(), wxjkSssjInfo.getIdNo());
        }

        // 每500个条目调用一次 baseSave(map)
        int batchSize = 2000;
        int count = 0;

        for (Long businessId : map.keySet()) {
            tempMap.put(businessId, map.get(businessId));
            count++;

            if (count >= batchSize) {
                List<GzxDebtorLiaisonReqDto> relationPhones = dataWxjkContactInfoService.queryByBussnissId(tempMap);
                if (!CollectionUtils.isEmpty(relationPhones)) {
                    gzxDebtorLiaisonFeign.sync(relationPhones);
                }
                try {
                    Thread.sleep(200L);
                } catch (InterruptedException e) {
                    log.info("中断线程异常，继续执行。。。。");
                }
                tempMap.clear();
                count = 0;
            }
        }

        // 处理剩余的条目
        if (!tempMap.isEmpty()) {
            List<GzxDebtorLiaisonReqDto> relationPhones = dataWxjkContactInfoService.queryByBussnissId(tempMap);
            if (!CollectionUtils.isEmpty(relationPhones)) {
                gzxDebtorLiaisonFeign.sync(relationPhones);
            }
        }
    }
}
